home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / ppl4c.exe / FILEXFER.C < prev    next >
Text File  |  1992-08-29  |  10KB  |  350 lines

  1. /*
  2. **                    ---  filexfer.c ---
  3. **
  4. **  Demonstration program for the Personal Protocol Library.
  5. **
  6. **  See FILEXFER.H for configuration parameters.
  7. **
  8. **  Do NOT select YMODEM-G when using a null modem cable unless you are
  9. **  certain that RTS & CTS are reversed ( this is often not true ).
  10. **
  11. */
  12. #include <stdio.h>
  13. #include "ppl4c.h"
  14. #include "ascii.h"
  15. #include "pcl4c.h"
  16. #include "filexfer.h"
  17.  
  18. #define FALSE 0
  19. #define TRUE !FALSE
  20. #define NO_ERROR 0
  21.  
  22. /*** protocol data ***/
  23.  
  24. static int BatchFlag = FALSE;
  25. static int OneKflag = FALSE;
  26. static char NCGchar = NAK;
  27.  
  28. /*** global variables ***/
  29.  
  30. static char PriRxBuf[2048];       /* Primary 2K receive buffer */
  31. static char SecRxBuf[2048];       /* Secondary 2K receive buffer */
  32. static int ThisPacket;            /* packet # */
  33. static char FileSpec[64];         /* file specification */
  34. static char EmptyFile[1] = "\0";
  35. static char *BaudRate[10] =  {"300","600","1200","2400","4800","9600",
  36.                             "19200","38400","57600","115200"};
  37.  
  38. static int LastPacket[2] = {-1,-1};
  39. static char Protocol[2] = {'X', 'X'};
  40. static int IsIdle[2] = {TRUE,TRUE};
  41. static int ThePort[2] = {PRI_PORT,SEC_PORT};
  42. static int TheBaud[2] = {PRI_BAUD,SEC_BAUD};
  43. /*static char *ThePrefix[2] = {"Primary","Secondary"};*/
  44. static char *TheBuffer[2] = {PriRxBuf,SecRxBuf};
  45. static char *ModelText[4] = {"Small","Compact","Medium","Large"};
  46.  
  47. char KeyRead();
  48. void UpdateStuff();
  49. void SetProtocol();
  50. void SayProtocol();
  51.  
  52. void main()
  53. {int i;
  54.  int Code;
  55.  char ch;
  56.  int C;
  57.  int Version;
  58.  void ErrorCheck();
  59.  char *Ptr;
  60.  /* display some info */
  61.  puts("\n*** FILEXFER 1.0:  Aug 10, 1992 ***");
  62.  Version = SioInfo('V');
  63.  printf("Library = %d.%d  ",Version/16,Version%16);
  64.  printf("Memory Model = %s\n",ModelText[3&SioInfo('M')] );
  65.  /*printf("Preparing %d channels\n",NBR_OF_CHANNELS);*/
  66.  for(C=0;C<NBR_OF_CHANNELS;C++)
  67.    {printf("Channel %d: ",C);
  68.     printf("Port = COM%d, ",1+ThePort[C]);
  69.     printf("Rate = %s\n",BaudRate[TheBaud[C]]);
  70.     ErrorCheck( SioRxBuf(ThePort[C],TheBuffer[C],Size2048) );
  71.     ErrorCheck( SioReset(ThePort[C],TheBaud[C]) );
  72.     /* set channel 0 to primary port, channel 1 to secondary port */
  73.     xyInit(C,ThePort[C]);
  74. #if RTS_CTS_CONTROL
  75.     SioFlow(ThePort[C],3*ONE_SEC);
  76.     printf("COM%d: Flow Control enabled. CTS = ",ThePort[C]);
  77.     if(SioCTS(ThePort[C])) puts("ON");
  78.     else puts("OFF");
  79. #endif
  80.     /* Set FIFO level if have 16550 UART */
  81.     if( SioFIFO(ThePort[C],LEVEL_14) ) printf("COM%d: INS16550 detected",1+ThePort[C]);
  82.     /* clear PCL4C receive buffer */
  83.     ErrorCheck( SioRxFlush(ThePort[C]) );
  84.     /* see FILEXFER.H for definition of AT_COMMAND_SET */
  85. #if AT_COMMAND_SET
  86.     /* wait for Modem to say its ready */
  87.     printf("Waiting for Modem DSR on COM%d.",1+ThePort[C]);
  88.     while( !SioDSR(ThePort[C]) )
  89.       {
  90.        if(SioKeyPress()||SioBrkKey()) MyExit(0,"Aborted by user");
  91.        putchar('.');
  92.        SioDelay(ONE_SEC);
  93.       }
  94.     putchar('\n');
  95.     /* initialize (Hayes compatible) modem */
  96.     SendTo(ThePort[C],"!AT!!~");
  97.     SendTo(ThePort[C],"!AT E1 S7=60 S11=60 V1 X1 Q0 S0=1!");
  98.     if(WaitFor(ThePort[C],"OK")) printf("\nCOM%d MODEM READY\n",ThePort[C]);
  99.     else printf("\nWARNING: Expected OK not received\n");
  100. #endif
  101.    } /* end for(C) */
  102.  /* begin main loop */
  103.  printf("\n");
  104.  while(1)
  105.    {
  106.     /* get user command */
  107.     printf("\nQ)uit P)rotocol S)end R)eceive A)bort C)omm Status:");
  108.     ch = KeyRead(); printf("\n");
  109.     /* update status for each channel */
  110.     for(C=0;C<NBR_OF_CHANNELS;C++) IsIdle[C] = xyDriver(C);
  111.     switch(toupper(ch))
  112.       {case 'Q':  /* QUIT */
  113.          for(C=0;C<NBR_OF_CHANNELS;C++) SioDone(ThePort[C]);
  114.          puts("Done");
  115.          exit(0);
  116.        case 'P':  /* SET PROTOCOL */
  117.          SetProtocol();
  118.          break;
  119.        case 'A':  /* ABORT TRANSFER */
  120.          C = GetChannel();
  121.          if(C!=ESC) xyAbort(C);
  122.          break;
  123.        case 'S':  /* SEND FILE */
  124.          if((C=GetChannel())==ESC) break;
  125.          if(IsIdle[C])
  126.            {if(GetString("Enter Filename:",FileSpec)==0) break;
  127.             if(!FindFirst(FileSpec))
  128.               {printf("No such file(s) '%s'\n",FileSpec);
  129.                break;
  130.               }
  131.             xyStartTx(C,FileSpec,OneKflag,BatchFlag);
  132.            }
  133.          else printf("C%d: Channel is busy\n",C);
  134.          break;
  135.        case 'R':  /* RECEIVE FILE */
  136.          if((C=GetChannel())==ESC) break;
  137.          if(IsIdle[C])
  138.            {if(BatchFlag)
  139.               {/* YMODEM provides filename */
  140.                xyStartRx(C,EmptyFile,NCGchar,BatchFlag);
  141.               }
  142.             else
  143.               {/* need filename 1st */
  144.                GetString("Enter Filename:",FileSpec);
  145.                xyStartRx(C,FileSpec,NCGchar,BatchFlag);
  146.               }
  147.            }
  148.          else printf("C%d: Channel is busy\n",C);
  149.          break;
  150.        case 'C':  /* COMM STATUS */
  151.          for(C=0;C<NBR_OF_CHANNELS;C++)
  152.            {/* get channel status */
  153.             Code = xyDriver(C);
  154.             if(Code<0)
  155.               {/* comm error returned */
  156.                printf("C%d: SIO Error %d",C,Code);
  157.                SioError(Code);
  158.               }
  159.             else
  160.               {/* no comm error */
  161.                if(IsIdle[C])
  162.                   {/* channel is idle */
  163.                    Code = xyGetErrorCode(C);
  164.                    if(Code==NO_ERROR)
  165.                      {/* no error on idle channel */
  166.                       printf("C%d: ",C);
  167.                       SayProtocol(Protocol[C]);
  168.                       printf(", channel is idle.\n");
  169.                      }
  170.                    else
  171.                      {/* report error condition */
  172.                       printf("C%d: '%c' Error '",C,Protocol[C]);
  173.                       xySayError(Code);
  174.                       printf("' occured in state '");
  175.                       xySayState(xyGetErrorState(C));
  176.                       printf("'\n");
  177.                      }
  178.                   }
  179.                else
  180.                   {/* channel is NOT idle */
  181.                    printf("C%d: ",C);
  182.                    SayProtocol(Protocol[C]);
  183.                    printf(", State='");
  184.                    xySayState(xyGetState(C));
  185.                    i = xyGetPacket(C);
  186.                    if(i>=0) printf("', Packet=%d",i);
  187.                    Ptr = xyGetFilename(C);
  188.                    if(strlen(Ptr)>0) printf(", File='%s'\n",Ptr);
  189.                    else printf("\n");
  190.                   }
  191.               }
  192.            } /* end for(C) */
  193.          break;
  194.       } /* end switch */
  195.    } /* end while */
  196. } /* end main */
  197.  
  198. char KeyRead()
  199. {/* all keyboard input MUST be called thru KeyRead */
  200.  while(!SioKeyPress()) UpdateStuff();
  201.  return( SioKeyRead() );
  202. } /* end KeyRead */
  203.  
  204. void UpdateStuff()
  205. {int C;
  206.  /* read each channel */
  207.  for(C=0;C<NBR_OF_CHANNELS;C++) IsIdle[C] = xyDriver(C);
  208. } /* end UpdateStuff */
  209.  
  210. void ErrorCheck(Code)
  211. int Code;
  212. {int C;
  213.  /* trap PCL error codes */
  214.  if(Code<0)
  215.      {SioError(Code);
  216.       for(C=0;C<NBR_OF_CHANNELS;C++) SioDone(ThePort[C]);
  217.       exit(1);
  218.      }
  219. } /* end ErrorCheck */
  220.  
  221. void SetProtocol()
  222. {char Answer;
  223.  int Flag;   /* change protocol if TRUE */
  224.  int C;
  225.  if((C=GetChannel())==ESC) return;
  226.  if(!IsIdle[C])
  227.    {printf("WARNING: Cannot change protocol until channel is idle\n");
  228.     return;
  229.    }
  230. #if RTS_CTS_CONTROL
  231.  printf("X: XMODEM   C: XMODEM-CRC   1: XMODEM-1K   Y: YMODEM   G: YMODEM-G\n");
  232.  printf("Enter X,C,1,Y, or G: ");
  233. #else
  234.  printf("X: XMODEM   C: XMODEM-CRC   1: XMODEM-1K   Y: YMODEM\n");
  235.  printf("Enter X,C,1, or Y: ");
  236. #endif
  237.  Answer = KeyRead();
  238.  SioCrtWrite(Answer);
  239.  Flag = TRUE;
  240.  switch( toupper(Answer) )
  241.    {case 'X':
  242.       BatchFlag = FALSE;
  243.       OneKflag = FALSE;
  244.       NCGchar = NAK;
  245.       break;
  246.     case 'C':
  247.       BatchFlag = FALSE;
  248.       OneKflag = FALSE;
  249.       NCGchar = 'C';
  250.       break;
  251.     case '1':
  252.       BatchFlag = FALSE;
  253.       OneKflag = TRUE;
  254.       NCGchar = 'C';
  255.       break;
  256.     case 'Y':
  257.       BatchFlag = TRUE;
  258.       OneKflag = TRUE;
  259.